

import socket,sys,hashlib,os,json
from sys import hash_info

class FtpClient(object):
    def __init__(self):
        self.client =socket.socket()

    def help(self):
        msg='''
        Client支持命令如下:
        ls                           <列出服务端目录和文件>
        pwd                          <显示当前工作目录>
        cd ..                        <切换到当前工作目录的上级目录>
        get filename                 <下载服务端文件>
        put filename                 <向服务端上传文件>
        rm filename                  <删除文件或目录>
        rename oldname newname       <重命名文件>
        unpack filename               <解压缩tar/zip文件>
        tz filename                 <压缩文件,参数依次是 finame tz_filename zip/tar>
        mkdir filename               <创建目录>
        sh list_args                 <远程执行shell命令>
        '''
        print(msg)
    def connect(self,ip,port):
        self.client.connect((ip,port))
    def interactive(self):
        while True:
            cmd=input(">>>:").strip()
            if len(cmd)==0:continue
            cmd_str=cmd.split()[0]
            if hasattr(self,"cmd_%s"%cmd_str):
                func=getattr(self,"cmd_%s"%cmd_str)
                func(cmd)
            else:
                self.help()
    def cmd_mkdir(self,*args):
        '''远程创建目录'''
        cmd_split=args[0].split()
        action=cmd_split[0]
        # parameter=cmd_split[1]
        filename=cmd_split[1]
        msg_dic={
            "action":action,
            "filename":filename,
        }
        self.client.send(json.dumps(msg_dic).encode("utf-8"))
        '''接收服务端反馈的结果'''
        self.data=self.client.recv(1024).strip()
        server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
        print("server_msg:",server_dic)

    def cmd_sh(self,*args):
        '''远程执行shell命令'''
        cmd_split=args[0].split()
        action=cmd_split[0]
        command=cmd_split[1:]
        msg_dic={
            "action":action,
            "command":command,
        }
        self.client.send(json.dumps(msg_dic).encode("utf-8"))
        '''接收服务端返回结果'''
        self.data=self.client.recv(10240).strip()
        server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
        print("server_msg:",server_dic["msg_server"]["stdout"])
        
    def cmd_unpack(self,*args):
        '''解压缩文件'''
        try:
            # os.chdir(MyTCPHandler.current_p)
            cmd_split=args[0].split()
            action=cmd_split[0]
            filename=cmd_split[1]
            msg_dic={
                "action":action,
                "filename":filename,
            }
            self.client.send(json.dumps(msg_dic).encode("utf-8"))
            '''接收服务端反馈的结果'''
            self.data=self.client.recv(1024).strip()
            server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
            print("server_msg:",server_dic)
        except:
            print("something wrong")
    
    def cmd_rename(self,*args):
        '''重命名服务端文件'''
        try:
            cmd_split=args[0].split()
            # print(cmd_split)
            action=cmd_split[0]
            oldname=cmd_split[1]
            newname=cmd_split[2]
            msg_dic={
                "action":action,
                "oldname" :oldname,
                "newname":newname,
            }
            self.client.send(json.dumps(msg_dic).encode("utf-8"))
            '''接收服务端返回结果'''
            while True:
                self.data=self.client.recv(1024).strip()
                server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
                print("server_msg:",server_dic)
                break
        except:
            print("something wrong!!")

    def cmd_tz(self,*args):
        '''归档打包文件目录'''
        try:
            cmd_split=args[0].split()
            action=cmd_split[0]
            filename=cmd_split[1]
            tz_filename=cmd_split[2]
            format=cmd_split[3]
            msg_dic={
                "action":action,
                "filename":filename,
                "tz_filename":tz_filename,
                "format":format,
            }
            self.client.send(json.dumps(msg_dic).encode("utf-8"))
            '''接收服务端反馈的结果'''
            self.data=self.client.recv(1024).strip()
            server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
            print("server_msg:",server_dic)
        except:
            print("something wrong")

    def cmd_cd(self,*args):
        '''切换工作目录'''
        try:
            cmd_split=args[0].split()
            # print(cmd_split)
            file=cmd_split[1]
            action=cmd_split[0]
            msg_dic={
                "action":action,
                "file" : file,
            }
            self.client.send(json.dumps(msg_dic).encode("utf-8"))
            # self.client.send(cmd_split.encode("utf-8"))
            '''接收服务端返回的查询结果'''
            while True:
                self.data=self.client.recv(1024).strip()
                server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
                print("current path:",server_dic["current_path"])
                print("file and directory:",server_dic["current_file"])
                print("server_msg:",server_dic["msg"])
                # for i in server_dic["current_file"]:
                #     print(i)
                break
        except:
            print("something wrong!!")
    
    def cmd_rm(self,*args):
        '''删除文件'''
        cmd_split=args[0].split()
        filename=cmd_split[1]
        action=cmd_split[0]
        msg_dic={
            "action":action,
            "filename":filename,
        }
        self.client.send(json.dumps(msg_dic).encode("utf-8"))
        '''接收服务端返回数据'''
        while True:
            self.data=self.client.recv(1024).strip()
            server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
            print(server_dic)
            # for i in server_dic['ls']:
            #     print(i)
            break

    def cmd_ls(self,*args):
        '''查看远端服务器当前目录下的文件和目录'''
        cmd_split=args[0].split()
        # print(cmd_split)
        msg_dic={
            "action":"ls",
        }
        self.client.send(json.dumps(msg_dic).encode("utf-8"))
        # self.client.send(cmd_split.encode("utf-8"))
        '''接收服务端返回的查询结果'''
        while True:
            self.data=self.client.recv(1024).strip()
            server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
            # print(server_dic)
            for i in server_dic['ls']:
                print(i)
            break
    
    def cmd_pwd(self,*args):
        '''查询服务当前工作路径'''
        cmd_split=args[0].split()
        # print(cmd_split)
        msg_dic={
            "action":"pwd",
        }
        self.client.send(json.dumps(msg_dic).encode("utf-8"))
        # self.client.send(cmd_split.encode("utf-8"))
        '''接收服务端返回的查询结果'''
        while True:
            self.data=self.client.recv(1024).strip()
            server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
            print(server_dic['pwd'])
            # for i in server_dic['pwd']:
            #     print(i)
            break

    def cmd_put(self,*args):
        ''''向服务端发送文件'''
        cmd_split=args[0].split()
        if len(cmd_split)>1:
            filename=cmd_split[1]
            if os.path.isfile(filename):
                file_size=os.stat(filename).st_size
                msg_dic={
                    "action":"put",
                    "filename" : filename,
                    "size":file_size,
                    "overriden":True,
                }
                self.client.send(json.dumps(msg_dic).encode("utf-8"))
                server_response=self.client.recv(1024)
                f=open(filename,"rb")
                print("[%s] start upload "%msg_dic)
                for line in f:
                    self.client.send(line)
                f.close()
                print("file send done!")
            else:
                print(filename,"is not exit")
                
    def cmd_get(self,*args):
        cmd_split=args[0].split()
        if len(cmd_split)>1:
            filename=cmd_split[1]
            msg_dic={
                "action":"get",
                "filename" : filename,
            }
            self.client.send(json.dumps(msg_dic).encode("utf-8"))
        else:
            pass
        '''接收服务端文件'''
        while True:
            self.data=self.client.recv(1024).strip()
            server_dic=json.loads(self.data.decode()) ##byte数据转str,json数据转字典数据
            print(server_dic)
            filename=server_dic["filename"]
            filesize=server_dic["filesize"]

            if os.path.isfile(filename):
                os.remove(filename)
                f=open(filename,"wb")
            else:
                f=open(filename,"wb")
            self.client.send(b"client has ready receive file")
            received_size=0
            while received_size<filesize:
                data=self.client.recv(1024)
                received_size+=len(data)
                f.write(data)
            else:
                print("file:[%s] has received"%filename)
                f.close()
                break
if __name__=="__main__":
    ftp=FtpClient()
    ftp.connect("localhost",9998)
    ftp.interactive()
